#include "cxicalendarwidget.h"
#include "yearmonthwidget.h"
#include <QDebug>
#include <QGuiApplication>
#include <QLocale>
#include <QPainter>
#include <QPushButton>
#include <QScreen>
#include <QTextCharFormat>
#include <QVBoxLayout>

CxiCalendarWidget::CxiCalendarWidget(QWidget* parent)
	: QCalendarWidget(parent),
	  m_iFontSize(14),
	  m_todayBtn(nullptr),
	  m_yearMonthWidget(new YearMonthWidget(this)),
	  m_topWidget(nullptr),
	  m_leftMonthBtn(nullptr),
	  m_rightMonthBtn(nullptr),
	  m_leftYearBtn(nullptr),
	  m_rightYearBtn(nullptr),
	  m_monthLabelBtn(nullptr),
	  m_yearLabelBtn(nullptr)
{
	connect(this, &QCalendarWidget::clicked, this, &CxiCalendarWidget::onUpdateHMSmmTime);
	initCalendar();
	setFixedSize(300, 300);

	connect(m_yearMonthWidget, &YearMonthWidget::yearMonthButtonIsclicked, this, &CxiCalendarWidget::onYearMonthButtonIsclicked);
}

CxiCalendarWidget::~CxiCalendarWidget()
{
}

void CxiCalendarWidget::paintCell(QPainter* painter, const QRect& rect, const QDate& date) const
{
	if (date == selectedDate())
	{
		//选中日期
		painter->save();
		painter->setRenderHint(QPainter::Antialiasing);
		painter->setPen(Qt::NoPen);
		painter->setBrush(QColor(0, 145, 255));
		QFont tmp = painter->font();
		tmp.setPixelSize(m_iFontSize);
		painter->setFont(tmp);

		painter->drawRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6);
		painter->setPen(QColor(255, 255, 255));

		painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
		painter->restore();
	}
	else if (date < minimumDate() || date > maximumDate())
	{
		//不可点击部分
		painter->save();
		painter->setRenderHint(QPainter::Antialiasing);
		painter->setPen(Qt::NoPen);
		painter->setBrush(QColor(249, 249, 249));

		painter->drawRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6);
		painter->setPen(QColor(220, 220, 220));

		QFont tmp = painter->font();
		tmp.setPixelSize(m_iFontSize);
		painter->setFont(tmp);
		painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
		painter->restore();
	}
	else if (date == QDate::currentDate())
	{
		//当前日期
		painter->save();
		QFont tmp = painter->font();
		tmp.setPixelSize(m_iFontSize);
		painter->setFont(tmp);
		painter->setRenderHint(QPainter::Antialiasing);
		painter->setPen(Qt::NoPen);
		painter->setBrush(QColor(0, 161, 255));
		painter->drawRect(rect.x(), rect.y() + 3, rect.width(), rect.height() - 6);
		painter->setBrush(QColor(255, 255, 255));
		painter->drawRect(rect.x() + 1, rect.y() + 4, rect.width() - 2, rect.height() - 8);
		painter->setPen(QColor(0, 161, 255));

		painter->drawText(rect, Qt::AlignCenter, QString::number(date.day()));
		painter->restore();
	}
	else
	{
		QCalendarWidget::paintCell(painter, rect, date);
	}
}

void CxiCalendarWidget::hideEvent(QHideEvent* event)
{
	if (m_yearMonthWidget)
	{
		m_yearMonthWidget->hide();
	}
}

void CxiCalendarWidget::initCalendar()
{
	layout()->setSizeConstraint(QLayout::SetDefaultConstraint);
	setNavigationBarVisible(false);
	setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
	setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
	setLocale(QLocale(QLocale::Chinese));

	QTextCharFormat format;
	format.setForeground(QColor(51, 51, 51));
	format.setBackground(QColor(255, 255, 255));
	format.setFontPointSize(16);
	QFont tmp;
	tmp.setPixelSize(16);
	format.setFont(tmp);

	setWeekdayTextFormat(Qt::Monday, format);
	setWeekdayTextFormat(Qt::Tuesday, format);
	setWeekdayTextFormat(Qt::Wednesday, format);
	setWeekdayTextFormat(Qt::Thursday, format);
	setWeekdayTextFormat(Qt::Friday, format);
	setWeekdayTextFormat(Qt::Saturday, format);
	setWeekdayTextFormat(Qt::Sunday, format);

	setFirstDayOfWeek(Qt::Monday);

	initTopWidget();
	initBottomWidget();

	connect(this, &QCalendarWidget::currentPageChanged, [this](int year, int month) {
		setDateLabelTimeText(year, month);
	});
}

void CxiCalendarWidget::initTopWidget()
{
	m_topWidget = new QWidget(this);
	m_topWidget->setObjectName("CalendarTopWidget");
	m_topWidget->setFixedHeight(40);
	m_topWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

	auto* hboxLayout = new QHBoxLayout;
	hboxLayout->setContentsMargins(12, 0, 12, 0);
	hboxLayout->setSpacing(4);

	m_leftYearBtn = new QPushButton(this);
	m_leftMonthBtn = new QPushButton(this);
	m_rightYearBtn = new QPushButton(this);
	m_rightMonthBtn = new QPushButton(this);
	//    m_dateLabel     = new QLabel(this);
	setTopButtonStyle();

	QFont tmp;
	tmp.setPixelSize(m_iFontSize);
	//    m_dateLabel->setFont(tmp);

	m_monthLabelBtn = new QPushButton(this);
	m_yearLabelBtn = new QPushButton(this);

	//    m_leftYearBtn->setFixedSize(16, 16);
	//    m_leftMonthBtn->setFixedSize(16, 16);
	//    m_rightYearBtn->setFixedSize(16, 16);
	//    m_rightMonthBtn->setFixedSize(16, 16);

	hboxLayout->addWidget(m_leftYearBtn);
	hboxLayout->addWidget(m_leftMonthBtn);
	hboxLayout->addStretch();
	//    hboxLayout->addWidget(m_dateLabel);
	hboxLayout->addWidget(m_monthLabelBtn);
	hboxLayout->addStretch();
	hboxLayout->addWidget(m_yearLabelBtn);
	hboxLayout->addStretch();
	hboxLayout->addWidget(m_rightMonthBtn);
	hboxLayout->addWidget(m_rightYearBtn);
	m_topWidget->setLayout(hboxLayout);
	//	m_topWidget->setStyleSheet(QString("QWidget {border-bottom: %1; background-color: %2; border-top-left-radius: %3px; border-top-right-radius: %4px; }")
	//									   .arg("1px solid #eeeeee", "rgb(255, 255, 255)", QString::number(4), QString::number(4)));

	QVBoxLayout* vBodyLayout = qobject_cast<QVBoxLayout*>(layout());
	vBodyLayout->insertWidget(0, m_topWidget);

	connect(m_leftYearBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));
	connect(m_leftMonthBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));
	connect(m_rightYearBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));
	connect(m_rightMonthBtn, SIGNAL(clicked()), this, SLOT(onbtnClicked()));
	connect(m_monthLabelBtn, &QPushButton::clicked, this, [=]() { showYearMonthList(Month); });
	connect(m_yearLabelBtn, &QPushButton::clicked, this, [=]() { showYearMonthList(Year); });

	setDateLabelTimeText(selectedDate().year(), selectedDate().month());
}

void CxiCalendarWidget::initBottomWidget()
{
	auto* bottomWidget = new QWidget(this);
	bottomWidget->setFixedHeight(40);
	bottomWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

	auto* hboxLayout = new QHBoxLayout;
	hboxLayout->setContentsMargins(12, 0, 12, 0);
	hboxLayout->setSpacing(0);

	m_todayBtn = new QPushButton(this);
	m_todayBtn->setFixedSize(40, 22);
	m_todayBtn->setText(QStringLiteral("今天"));

	hboxLayout->addStretch();
	hboxLayout->addWidget(m_todayBtn);
	hboxLayout->addStretch();
	bottomWidget->setLayout(hboxLayout);

	//	bottomWidget->setStyleSheet(QString("QWidget {border-top: %1; background-color: %2; border-top-left-radius: %3px; border-top-right-radius: %4px; }")
	//										.arg("1px solid #eeeeee", "rgb(255, 255, 255)", QString::number(4), QString::number(4)));

	auto* vBodyLayout = qobject_cast<QVBoxLayout*>(layout());
	vBodyLayout->addWidget(bottomWidget);

	connect(m_todayBtn, &QPushButton::clicked, [this]() {
		//点击今天，设置为当前日期
		this->setSelectedDate(QDate::currentDate());

		QDateTime timeDate;
		timeDate.setDate(selectedDate());
		emit signalSetCalendarTime(timeDate);
	});
}

void CxiCalendarWidget::setDateLabelTimeText(int year, int month)
{
	//    m_dateLabel->setText(QStringLiteral("%1月 %2").arg(month).arg(year));
	m_monthLabelBtn->setText(QStringLiteral("%1").arg(m_yearMonthWidget->convertMonthText(month)));
	m_yearLabelBtn->setText(QStringLiteral("%1").arg(year));
}

void CxiCalendarWidget::setTopButtonStyle()
{
	int btn_width = 16;
	int btn_height = 16;

	// 左移年按钮图标（正常/hover/按下状态）
	QIcon leftYearIcon;
	leftYearIcon.addPixmap(QPixmap(":/icon/previousyear.png"), QIcon::Normal);

	// 左移月按钮图标
	QIcon leftMonthIcon;
	leftMonthIcon.addPixmap(QPixmap(":/icon/previousmonth.png"), QIcon::Normal);

	// 右移年按钮图标
	QIcon rightYearIcon;
	rightYearIcon.addPixmap(QPixmap(":/icon/nextyear.png"), QIcon::Normal);

	// 右移月按钮图标
	QIcon rightMonthIcon;
	rightMonthIcon.addPixmap(QPixmap(":/icon/nextmonth.png"), QIcon::Normal);

	// 设置按钮图标和大小
	auto setButtonIcon = [&](QPushButton* btn, const QIcon& icon) {
		btn->setIcon(icon);
		btn->setIconSize(QSize(btn_width, btn_height));// 设置图标大小
		btn->setFixedSize(btn_width, btn_height);      // 设置按钮大小
		btn->setFlat(true);                            // 扁平样式，无默认背景
	};

	// 应用图标到各个按钮
	setButtonIcon(m_leftYearBtn, leftYearIcon);
	setButtonIcon(m_leftMonthBtn, leftMonthIcon);
	setButtonIcon(m_rightYearBtn, rightYearIcon);
	setButtonIcon(m_rightMonthBtn, rightMonthIcon);
}

void CxiCalendarWidget::setButtonStyle(QPushButton* btn, const int width, const int height, const QStringList& icons)
{
	if (!btn || icons.size() < 3)
	{
		return;
	}
	//	QString btnStyle = QString("QPushButton { width: %1px; height: %2px; border-image: %3; } \n"
	//							   "QPushButton:hover { border-image: %4; } \n"
	//							   "QPushButton:pressed { border-image: %5; }")
	//							   .arg(QString::number(width), QString::number(height), icons.at(0), icons.at(1), icons.at(2));
	//
	//
	//	btn->setStyleSheet(btnStyle);
}

void CxiCalendarWidget::showYearMonthList(CxiCalendarWidget::DateType type)
{
	QRect rect = QGuiApplication::primaryScreen()->availableGeometry();
	int posX = (type == Month) ? m_monthLabelBtn->x() : m_yearLabelBtn->x();
	QPoint gloadPos = mapToGlobal(QPoint(posX - 5, m_topWidget->height()));
	if (gloadPos.y() + m_yearMonthWidget->height() > rect.height())
	{
		int y = gloadPos.y() - this->height() - m_yearMonthWidget->height();
		gloadPos.setY(y);
	}

	m_yearMonthWidget->move(gloadPos);
	m_yearMonthWidget->showYearMonthWidget(type);
}

void CxiCalendarWidget::onbtnClicked()
{
	auto* senderBtn = qobject_cast<QPushButton*>(sender());
	if (senderBtn == m_leftYearBtn)
	{
		showPreviousYear();
	}
	else if (senderBtn == m_leftMonthBtn)
	{
		showPreviousMonth();
	}
	else if (senderBtn == m_rightYearBtn)
	{
		showNextYear();
	}
	else if (senderBtn == m_rightMonthBtn)
	{
		showNextMonth();
	}
}

void CxiCalendarWidget::onUpdateHMSmmTime(const QDate& date)
{
	// 点击日期即选中该日志
	QDateTime timeDate;
	timeDate.setDate(selectedDate());
	emit signalSetCalendarTime(timeDate);
}

void CxiCalendarWidget::onYearMonthButtonIsclicked(int type, int newValue)
{
	QDate currentDate = this->selectedDate();// 获取当前选中的日期
	if (type == Month)
	{
		currentDate.setDate(currentDate.year(), newValue, currentDate.day());// 设置为4月
	}
	else
	{
		currentDate.setDate(newValue, currentDate.month(), currentDate.day());// 设置为4月
	}

	this->setSelectedDate(currentDate);// 设回去，只改变月份或者年
	setDateLabelTimeText(currentDate.year(), currentDate.month());
}
